
//思想不错，效率太低，放弃

package resources
{
	import flash.display.Bitmap;
	import flash.display.Loader;
	import flash.display.LoaderInfo;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.net.URLRequest;
	import flash.system.ApplicationDomain;
	import flash.system.LoaderContext;
	import flash.utils.Dictionary;
	import flash.utils.clearTimeout;
	import flash.utils.setTimeout;

	public class SceneResProviderQueue implements IResourceProvider
	{
		static private var _instance:SceneResProviderQueue;
		static public function get instance():SceneResProviderQueue
		{
			if(!_instance)
			{
				new SceneResProviderQueue;
			}
			
			return _instance;
		}
		
		protected var _updateProgress:Function;
		protected var _loadComplete:Function;
		
		//key identifier value resource
		protected var _resInfos:Dictionary;
		
		protected var _loader:Loader;
		protected var _urlReq:URLRequest;
		private var _loadContext:LoaderContext = new LoaderContext(false,ApplicationDomain.currentDomain);
		
		private var _currentLoading:CResLoadingItem;
		
		//CResLoadingItem
		private var _loadingQueue:Array = [];
		//key identifier value CResLoadingItem
//		private var _loadingQueueIndx:Dictionary = new Dictionary();
		
		private var _startLoadTimeout:int = 0;
		private var _totalNum:int = 0;
		private var _loadedNum:int = 0;
		private var _loadItemTimeInterval:int = 0;
		
		public function SceneResProviderQueue():void
		{
			if(_instance)
			{
				throw new Error("singleton error");
			}
			_instance = this;
			
			init();
		}
		
		private function init():void
		{
			_resInfos = new Dictionary();
			_loader = new Loader();
			_urlReq = new URLRequest();
			
			addEvents();
		}
		
		private function addEvents():void
		{
			_loader.contentLoaderInfo.addEventListener(Event.COMPLETE,onLoadItemComplete);
			_loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,onLoadError);
			_loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS,onItemProgress);
		}
		
		private function removeEvents():void
		{
			_loader.contentLoaderInfo.removeEventListener(Event.COMPLETE,onLoadItemComplete);
			_loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR,onLoadError);
			_loader.contentLoaderInfo.removeEventListener(ProgressEvent.PROGRESS,onItemProgress);
		}
		
		private function onLoadItemComplete(e:Event):void
		{
			var loadinfo:LoaderInfo = e.target as LoaderInfo;
			if(loadinfo)
			{
				var bmp:Bitmap = loadinfo.content as Bitmap;
				if(bmp)
				{
					var res:ImageResource = _resInfos[_currentLoading._identifier];
					if(!res)
					{
						res = new ImageResource();
						
						_resInfos[_currentLoading._identifier] = res;
					}
					
					res.initialize(bmp);
				}
				
				++this._loadedNum;
				if(_updateProgress != null)
				{
					_updateProgress(this._loadedNum,this._totalNum);
				}
				
//				delete _loadingQueueIndx[_currentLoading._identifier];
				this._currentLoading = null;
				flash.utils.clearTimeout(_startLoadTimeout);
				_startLoadTimeout = 0;
				
				startLoad();
			}
		}
		
		public function startLoad():void
		{
			if(_loadingQueue && _loadingQueue.length < 1)
			{
				if(_loadComplete != null)
				{
					_loadComplete();					
					
					_loadedNum = 0;
					_totalNum = 0;
				}
				return ;
			}
			
			if(_startLoadTimeout > 0)
			{
				return ;
			}
			
			if(_loadItemTimeInterval > 0)
			{
				_startLoadTimeout = flash.utils.setTimeout(realLoad,_loadItemTimeInterval);
			}
			else
			{
				realLoad();
			}
		}
		
		private function realLoad():void
		{
			if(this._currentLoading)
			{
				return ;
			}
			
			this._currentLoading = this._loadingQueue.shift();
			if(this._currentLoading)
			{
				this._urlReq.url = this._currentLoading._url;
				this._loader.load(this._urlReq,this._loadContext);
			}
		}
		
		private function onLoadError(e:IOErrorEvent):void
		{
			this._currentLoading = null;
			flash.utils.clearTimeout(this._startLoadTimeout);
			this._startLoadTimeout = 0;
			this.startLoad();
		}
		
		private function onItemProgress(e:ProgressEvent):void
		{
		}
		
		public function addImage(url:String,identifier:int):void
		{
			++this._totalNum;
			this._loadingQueue.push(CResLoadingItem.createItem(url,identifier));
		}
		
		public function getImage(url:String,identifier:int,forceReload:Boolean = false):Resource
		{
			var res:ImageResource = this._resInfos[identifier];
			if(res)
			{
				return res;
			}		
			
			return null;
		}
		
		public function clearAllImages():void
		{
			for each(var v:* in this._resInfos)
			{				
				v = null;
			}
			
			this._currentLoading = null;
			this._loadingQueue.splice(0);
			this._startLoadTimeout = 0;
			this._loadedNum = 0;
			this._totalNum = 0;
		}
		
		public function startPreLoad(updateProgress:Function,loadComplete:Function):void
		{
			this._updateProgress = updateProgress;
			this._loadComplete = loadComplete;
		}
		
		public function set loadItemTimeInterval(v:int):void
		{
			this._loadItemTimeInterval = v;
		}
		
		public function get loadItemTimeInterval():int
		{
			return this._loadItemTimeInterval;
		}
	}
}

class CResLoadingItem
{
	public static function createItem(url:String,id:int,f:Boolean = false):CResLoadingItem
	{
		var _t:CResLoadingItem = new CResLoadingItem();
		_t._url = url;
		_t._identifier = id;
		_t._forceReload = f;
		
		return _t;
	}
	
	public var _url:String;
	public var _identifier:int;
	public var _forceReload:Boolean;
}